using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.Xml;

using ICSharpCode.SharpZipLib.Zip;

using ClientTools.Client.Controls.Packager.PackageClasses;

namespace ClientTools.Client.Controls.Packager
{
    public partial class ucPackager : BaseUserControl, IUserControl
    {
        private PackageClasses.UmbPackage _umbPackage;
        private string _packagePath;
        private string _packageFilePath;
        private string _packageFolderPath;
        private PackagerUsageEnum _packagerUsage = PackagerUsageEnum.NotDefined;
        private BindingSource _bindingSource;

        public ucPackager()
        {
            InitializeComponent();
        }

        #region IUserControl Member

        public void SetData(ClientTools.Client.Library.Settings.Profile profile)
        {
            this.ActProfile = profile;
            this.ActProfile.InitProvider();
            this.ActProvider = this.ActProfile.ProviderObject;

            this.InitializeGrids();

            this.tabControl1.Enabled = false;

        }

        public string Header
        {
            get { return "Packager"; }
        }

        public Image ButtonImage
        {
            get { return this.tsbPackager.Image; }
        }

        public int Sort
        {
            get { return 101; }
        }

        public bool ShowDelimiter
        {
            get { return true; }
        }

        public string ButtonText
        {
            get { return "Packager"; }
        }

        #endregion

        private void InitializeGrids()
        {
            //Commanda
            this.dgvCommands.AutoGenerateColumns = false;
            DataGridViewTextBoxColumn tbc = new DataGridViewTextBoxColumn() { Name = "Assembly", DataPropertyName = "Assembly" };
            this.dgvCommands.Columns.Add(tbc);
            tbc = new DataGridViewTextBoxColumn() { Name = "TypeName", DataPropertyName = "TypeName" };
            this.dgvCommands.Columns.Add(tbc);
            DataGridViewComboBoxColumn cbc = new DataGridViewComboBoxColumn() { Name = "RunAt", DataPropertyName = "RunAt" };
            cbc.DataSource = Enum.GetValues(typeof(PackageClasses.RunAtEnum));
            this.dgvCommands.Columns.Add(cbc);

            this.dgvDocumentTypes.AutoGenerateColumns = false;
            tbc = new DataGridViewTextBoxColumn() { Name = "Name", DataPropertyName = "Name" };
            this.dgvDocumentTypes.Columns.Add(tbc);
            tbc = new DataGridViewTextBoxColumn() { Name = "Alias", DataPropertyName = "Alias" };
            this.dgvDocumentTypes.Columns.Add(tbc);

            if (this.ImplementsPackager())
            {
                try
                {
                    //ClientTools.Library.Macros.MacroCollection macros = ((global::ClientTools.Client.Library.Provider.WebserviceProvider)this.ActProvider).GetMacros();
                    //this.dgvMacros.AutoGenerateColumns = false;

                }
                catch (Exception)
                {
                }
            }
            else
            {

            }
        }

        private void ucPackager_Load(object sender, EventArgs e)
        {
            global::ClientTools.Client.Controls.GridViewHelper.SetGridLayout(this.dgvCommands);
            global::ClientTools.Client.Controls.GridViewHelper.SetGridLayout(this.dgvDocuments);
            global::ClientTools.Client.Controls.GridViewHelper.SetGridLayout(this.dgvDocumentTypes);
            global::ClientTools.Client.Controls.GridViewHelper.SetGridLayout(this.dgvFiles);
            global::ClientTools.Client.Controls.GridViewHelper.SetGridLayout(this.dgvMacroProperties);
            global::ClientTools.Client.Controls.GridViewHelper.SetGridLayout(this.dgvMacros);
            global::ClientTools.Client.Controls.GridViewHelper.SetGridLayout(this.dgvStylesheets);
            global::ClientTools.Client.Controls.GridViewHelper.SetGridLayout(this.dgvTemplates);
            global::ClientTools.Client.Controls.GridViewHelper.SetGridLayout(this.dgvAllowedTemplates);
            global::ClientTools.Client.Controls.GridViewHelper.SetGridLayout(this.dgvTabs);
            global::ClientTools.Client.Controls.GridViewHelper.SetGridLayout(this.dgvStructure);
            global::ClientTools.Client.Controls.GridViewHelper.SetGridLayout(this.dgvGenericProperties);
        }

        private void tsbNewPackage_Click(object sender, EventArgs e)
        {
            this._packagerUsage = PackagerUsageEnum.NewPackage;
            this._umbPackage = new ClientTools.Client.Controls.Packager.PackageClasses.UmbPackage();
            this._umbPackage.Info.Author.Name = "Author";
            this._umbPackage.Info.Author.Website = "Website";
            this._umbPackage.Info.Package.IsNewPackage = true;
            this._umbPackage.Info.Package.License.Text = "License";
            this._umbPackage.Info.Package.License.Url = "License url";
            this._umbPackage.Info.Package.Name = "Package name";
            this._umbPackage.Info.Package.Requirements.Major = 3;
            this._umbPackage.Info.Package.Requirements.Minor = 0;
            this._umbPackage.Info.Package.Requirements.Patch = 0;
            this._umbPackage.Info.Package.Url = "Url to package location";
            this._umbPackage.Info.Package.Version = "1.0.0";
            this._umbPackage.Info.Readme = "Put here the readme text";
            this.BindPackageData();
        }

        private void tsbOpenPackage_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.CheckFileExists = true;
            dlg.CheckPathExists = true;
            dlg.Filter = "umbraco packages (*.umb)|*.umb";
            dlg.Multiselect = false;
            dlg.Title = "Select umbraco package";
            if (dlg.ShowDialog(this) == DialogResult.OK)
            {
                this._packagerUsage = PackagerUsageEnum.OpenPackage;
                this._packagePath = dlg.FileName;
                this._packageFolderPath = this.ExtractZipFile(this._packagePath);
                if (this.LoadPackageFile(Path.Combine(this._packageFolderPath, "package.xml")))
                {
                    foreach (PackageClasses.File file in this._umbPackage.Files)
                    {
                        string path = Path.Combine(this._packageFolderPath, file.Guid);
                        if (System.IO.File.Exists(path))
                        {
                            file.FilePath = path;
                        }
                    }
                    this.BindPackageData();
                }
            }
        }

        private bool LoadPackageFile(string packageFileName)
        {
            XmlSerializer ser = new XmlSerializer(typeof(PackageClasses.UmbPackage));
            using (FileStream fs = new FileStream(packageFileName, FileMode.Open))
            {
                try
                {
                    this._umbPackage = (PackageClasses.UmbPackage)ser.Deserialize(fs);
                    fs.Close();
                    return true;
                }
                catch (InvalidOperationException ex)
                {
                    MessageBox.Show("The package file (package.xml) couldn't be deserialized. Please contact the package distributor.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }
            }
        }

        private string ExtractZipFile(string zipFileName)
        {
            string tempDirName = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(tempDirName);

            ZipInputStream s = new ZipInputStream(System.IO.File.OpenRead(zipFileName));
            ZipEntry theEntry;
            while ((theEntry = s.GetNextEntry()) != null)
            {
                string fileName = Path.GetFileName(theEntry.Name);

                if (fileName != String.Empty)
                {
                    FileStream streamWriter = System.IO.File.Create(Path.Combine(tempDirName, fileName));

                    int size = 2048;
                    byte[] data = new byte[2048];
                    while (true)
                    {
                        size = s.Read(data, 0, data.Length);
                        if (size > 0)
                        {
                            streamWriter.Write(data, 0, size);
                        }
                        else
                        {
                            break;
                        }
                    }
                    streamWriter.Close();
                }
            }

            s.Close();
            return tempDirName;
        }

        private void BindPackageData()
        {
            this._bindingSource = new BindingSource();
            this._bindingSource.DataSource = this._umbPackage;

            this.txtPackageName.DataBindings.Clear();
            this.txtPackageName.DataBindings.Add("Text", this._umbPackage.Info.Package, "Name");
            this.txtVersion.DataBindings.Clear();
            this.txtVersion.DataBindings.Add("Text", this._umbPackage.Info.Package, "Version");
            this.txtLicense.DataBindings.Clear();
            this.txtLicense.DataBindings.Add("Text", this._umbPackage.Info.Package.License, "Text");
            this.txtLicenseUrl.DataBindings.Clear();
            this.txtLicenseUrl.DataBindings.Add("Text", this._umbPackage.Info.Package.License, "Url");
            this.txtUrl.DataBindings.Clear();
            this.txtUrl.DataBindings.Add("Text", this._umbPackage.Info.Package, "Url");
            this.txtRequirementsMajor.DataBindings.Clear();
            this.txtRequirementsMajor.DataBindings.Add("Text", this._umbPackage.Info.Package.Requirements, "Major");
            this.txtRequirementsMinor.DataBindings.Clear();
            this.txtRequirementsMinor.DataBindings.Add("Text", this._umbPackage.Info.Package.Requirements, "Minor");
            this.txtRequirementsPatch.DataBindings.Clear();
            this.txtRequirementsPatch.DataBindings.Add("Text", this._umbPackage.Info.Package.Requirements, "Patch");
            this.txtAuthorName.DataBindings.Clear();
            this.txtAuthorName.DataBindings.Add("Text", this._umbPackage.Info.Author, "Name");
            this.txtAuthorWebsite.DataBindings.Clear();
            this.txtAuthorWebsite.DataBindings.Add("Text", this._umbPackage.Info.Author, "Website");
            this.txtReadme.DataBindings.Clear();
            this.txtReadme.DataBindings.Add("Text", this._umbPackage.Info, "Readme");

            this.dgvCommands.DataSource = this._umbPackage.Commands;
            this.dgvMacros.DataSource = this._umbPackage.Macros;
            this.dgvMacroProperties.DataSource = this._umbPackage.Macros;
            this.dgvMacroProperties.DataMember = "Properties"; 
            this.dgvFiles.DataSource = this._umbPackage.Files;
            this.dgvDocuments.DataSource = this._umbPackage.Documents;

            this.dgvDocumentTypes.DataSource = this._umbPackage.DocumentTypes;
            this.dgvGenericProperties.DataSource = this._umbPackage.DocumentTypes;
            this.dgvGenericProperties.DataMember = "GenericProperties";
            this.dgvGenericProperties.Columns["DescriptionCdata"].Visible = false;
            this.dgvAllowedTemplates.DataSource = this._umbPackage.DocumentTypes;
            this.dgvAllowedTemplates.DataMember = "Info.AllowedTemplates";
            this.dgvStructure.DataSource = this._umbPackage.DocumentTypes;
            this.dgvStructure.DataMember = "Structure";
            this.dgvTabs.DataSource = this._umbPackage.DocumentTypes;
            this.dgvTabs.DataMember = "Tabs";
            this.txtDocumentTypeAlias.DataBindings.Clear();
            this.txtDocumentTypeAlias.DataBindings.Add("Text", this._umbPackage.DocumentTypes, "Info.Alias");
            this.txtDocumentTypeDefaultTemplate.DataBindings.Clear();
            this.txtDocumentTypeDefaultTemplate.DataBindings.Add("Text", this._umbPackage.DocumentTypes, "Info.DefaultTemplate");
            this.txtDocumentTypeIcon.DataBindings.Clear();
            this.txtDocumentTypeIcon.DataBindings.Add("Text", this._umbPackage.DocumentTypes, "Info.Icon");
            this.txtDocumentTypeName.DataBindings.Clear();
            this.txtDocumentTypeName.DataBindings.Add("Text", this._umbPackage.DocumentTypes, "Info.Name");
            this.txtDocumentTypeThumbnail.DataBindings.Clear();
            this.txtDocumentTypeThumbnail.DataBindings.Add("Text", this._umbPackage.DocumentTypes, "Info.Thumbnail");

            this.dgvTemplates.DataSource = this._umbPackage.Templates;
            this.dgvStylesheets.DataSource = this._umbPackage.Stylesheets;
            this.dgvStylesheets.Columns["Content"].Visible = false;
            this.dgvStylesheets.Columns["ContentCdata"].Visible = false;


            this.rtbDocument.DataBindings.Clear();
            this.rtbStylesheetContent.DataBindings.Clear();
            this.rtbTemplate.DataBindings.Clear();

            this.rtbTemplate.DataBindings.Add("Text", this._umbPackage.Templates, "Design");
            this.rtbStylesheetContent.DataBindings.Add("Text", this._umbPackage.Stylesheets, "Content");
            
            this.tabControl1.Enabled = true;
            this.tabControl1.SelectedTab = tabInfo;
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            PackageClasses.UmbPackage p = new ClientTools.Client.Controls.Packager.PackageClasses.UmbPackage();
            p.Info.Author.Name = "TH";
            p.Info.Author.Website = "thoehler.com";
            p.Info.Package.License.Url = "licence url";
            p.Info.Package.License.Text = "licence text";
            p.Info.Package.Name = "package name";
            p.Info.Package.Requirements.Major = 1;
            p.Info.Package.Requirements.Minor = 2;
            p.Info.Package.Requirements.Patch = 3;
            p.Info.Package.Url = "url...";
            p.Info.Package.Version = "1.2.3";

            p.Info.Readme = "<p>Radme</p>";

            command c = new command() { Assembly = "assem", RunAt = RunAtEnum.start, TypeName = "typename"};
            p.Commands.Add(c);

            Macro m = new Macro() { Alias = "macroalias", Name = "name", RefreshRate = 0, ScriptAssembly = "assembly", ScriptType = "scripttype", UseInEditor = true, Xslt = "xslt" };
            MacroProperty mp = new MacroProperty() { Alias = "Alias", Name = "Name", PropertyType = "Property type", Show = true};
            m.Properties.Add(mp);
            p.Macros.Add(m);

            PackageClasses.File f = new ClientTools.Client.Controls.Packager.PackageClasses.File();
            f.Guid = "guid";
            f.OrgName = "orgname";
            f.OrgPath = "orgpath";
            p.Files.Add(f);


            PackageClasses.Template t = new ClientTools.Client.Controls.Packager.PackageClasses.Template();
            t.Alias = "alias";
            t.Design = "Design";
            t.Master = "Master";
            t.Name = "name...";
            p.Templates.Add(t);

            PackageClasses.Stylesheet st = new ClientTools.Client.Controls.Packager.PackageClasses.Stylesheet();
            st.Content = "Put in here the stypesheet content...";
            st.FileName = "filename.cs";
            st.Name = "my stylesheet";
            p.Stylesheets.Add(st);

            PackageClasses.DocumentSet ds = new ClientTools.Client.Controls.Packager.PackageClasses.DocumentSet();
            ds.ImportMode = "root";
            p.Documents.Add(ds);

            ds = new ClientTools.Client.Controls.Packager.PackageClasses.DocumentSet();
            ds.ImportMode = "root";
            p.Documents.Add(ds);

            PackageClasses.Node n = new ClientTools.Client.Controls.Packager.PackageClasses.Node();
            n.Id = 1;
            n.Version = Guid.NewGuid();
            ds.Nodes.Add(n);

            n = new ClientTools.Client.Controls.Packager.PackageClasses.Node();
            n.Id = 2;
            n.Version = Guid.NewGuid();
            ds.Nodes.Add(n);

            PackageClasses.Data da = new ClientTools.Client.Controls.Packager.PackageClasses.Data();
            da.Alias = "alias";
            da.Content = "Content...";
            da.VersionId = Guid.NewGuid();
            n.DataCollection.Add(da);

            da = new ClientTools.Client.Controls.Packager.PackageClasses.Data();
            da.Alias = "alias";
            da.Content = "Content...";
            da.VersionId = Guid.NewGuid();
            n.DataCollection.Add(da);

            using (System.IO.FileStream fs = new System.IO.FileStream(@"D:\\temp\\newpackage.xml", System.IO.FileMode.Create))
            {
                XmlSerializer ser = new XmlSerializer(typeof(PackageClasses.UmbPackage));
                ser.Serialize(fs, p);
                fs.Close();
            }
            MessageBox.Show("feddisch");
            //p.Info.Author
        }

        private void tsbAddCommand_Click(object sender, EventArgs e)
        {
            PackageClasses.command c = new ClientTools.Client.Controls.Packager.PackageClasses.command();
            c.Assembly = "Assembly name";
            c.RunAt = ClientTools.Client.Controls.Packager.PackageClasses.RunAtEnum.end;
            c.TypeName = "Type name";
            this._umbPackage.Commands.Add(c);
        }

        private void tsbDeleteCommand_Click(object sender, EventArgs e)
        {
            if (this.dgvCommands.SelectedRows.Count == 1)
            {
                this._umbPackage.Commands.Remove((PackageClasses.command)this.dgvCommands.SelectedRows[0].DataBoundItem);
            }
        }

        private void tsbNewMacro_Click(object sender, EventArgs e)
        {
            PackageClasses.Macro m = new ClientTools.Client.Controls.Packager.PackageClasses.Macro();
            m.Alias = "Alias";
            m.Name = "Name";
            m.RefreshRate = 0;
            m.ScriptAssembly = "Script Assembly";
            m.ScriptType = "Script Type";
            m.UseInEditor = false;
            m.Xslt = "";
            this._umbPackage.Macros.Add(m);
        }

        private void tsbDeleteMacro_Click(object sender, EventArgs e)
        {
            if (this.dgvMacros.SelectedRows.Count == 1)
            {
                this._umbPackage.Macros.Remove((PackageClasses.Macro)this.dgvMacros.SelectedRows[0].DataBoundItem);
            }
        }

        private void tsbAddProperty_Click(object sender, EventArgs e)
        {
            if (this.dgvMacros.SelectedRows.Count == 1)
            {
                PackageClasses.Macro m = (PackageClasses.Macro)this.dgvMacros.SelectedRows[0].DataBoundItem;
                PackageClasses.MacroProperty p = new ClientTools.Client.Controls.Packager.PackageClasses.MacroProperty();
                p.Alias = "Alias";
                p.Name = "Name";
                p.PropertyType = "Property type";
                p.Show = true;
                m.Properties.Add(p);
            }
        }

        private void tsbDeleteProperty_Click(object sender, EventArgs e)
        {
            if (this.dgvMacros.SelectedRows.Count == 1 && this.dgvMacroProperties.SelectedRows.Count == 1)
            {
                PackageClasses.Macro m = (PackageClasses.Macro)this.dgvMacros.SelectedRows[0].DataBoundItem;
                m.Properties.Remove((PackageClasses.MacroProperty)this.dgvMacroProperties.SelectedRows[0].DataBoundItem);
            }
        }

        private void tsbOpenPackageFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.CheckFileExists = true;
            dlg.CheckPathExists = true;
            dlg.Filter = "Umbraco package file (package.xml)|package.xml|All xml files (*.xml)|*.xml|All files (*.*)|*.*";
            dlg.Multiselect = false;
            dlg.Title = "Select umbraco package file";
            if (dlg.ShowDialog(this) == DialogResult.OK)
            {
                this._packagerUsage = PackagerUsageEnum.OpenPackageFile;
                this._packageFilePath = dlg.FileName;
                if (this.LoadPackageFile(dlg.FileName))
                {
                    this.BindPackageData();
                }
            }
        }

        private void tsbCreatePackageFile_Click(object sender, EventArgs e)
        {
            this._packagerUsage = PackagerUsageEnum.NewPackageFile;
            this._umbPackage = new ClientTools.Client.Controls.Packager.PackageClasses.UmbPackage();
            this._umbPackage.Info.Author.Name = "TH";
            this._umbPackage.Info.Author.Website = "thoehler.com";
            this._umbPackage.Info.Package.License.Url = "licence url";
            this._umbPackage.Info.Package.License.Text = "licence text";
            this._umbPackage.Info.Package.Name = "package name";
            this._umbPackage.Info.Package.Requirements.Major = 3;
            this._umbPackage.Info.Package.Requirements.Minor = 0;
            this._umbPackage.Info.Package.Requirements.Patch = 0;
            this._umbPackage.Info.Package.Url = "url...";
            this._umbPackage.Info.Package.Version = "1.0.0";
            this._umbPackage.Info.Readme = "<p>Radme</p>";

            this.BindPackageData();
        }

        private void tsbAddMacroFromUmbraco_Click(object sender, EventArgs e)
        {
            if (base.ImplementsPackager())
            {
                ClientTools.Library.Macros.MacroCollection macroCollection = ((Library.Interfaces.IPackager)base.ActProvider).GetMacros();
                Dialogs.AddDialog dlg = new ClientTools.Client.Controls.Packager.Dialogs.AddDialog();
                dlg.DataSource = macroCollection;
                if (dlg.ShowDialog(this) == DialogResult.OK)
                {
                    ClientTools.Library.Macros.Macro selectedMacro = (ClientTools.Library.Macros.Macro)dlg.SelectedItem;
                    if (selectedMacro == null)
                    {
                        MessageBox.Show("No macro selected...", "Error", MessageBoxButtons.OK);
                        return;
                    }
                    PackageClasses.Macro m = new ClientTools.Client.Controls.Packager.PackageClasses.Macro();
                    m.Alias = selectedMacro.Alias;
                    m.ScriptAssembly = selectedMacro.Assembly;
                    m.Name = selectedMacro.Name;
                    m.RefreshRate = selectedMacro.RefreshRate;
                    m.ScriptType = selectedMacro.Type;
                    m.UseInEditor = selectedMacro.UseInEditor;
                    m.Xslt = selectedMacro.Xslt;

                    foreach (ClientTools.Library.Macros.MacroProperty selectedProperty in selectedMacro.Properties)
	                {
                        PackageClasses.MacroProperty p = new ClientTools.Client.Controls.Packager.PackageClasses.MacroProperty();
                        p.Alias = selectedProperty.Alias;
                        p.Name = selectedProperty.Name;
                        p.PropertyType = selectedProperty.Type;
                        p.Show = selectedProperty.Public;
                        m.Properties.Add(p);
	                }

                    this._umbPackage.Macros.Add(m); 
                }
            }
        }

        private void tsbAddTemplateFromUmbraco_Click(object sender, EventArgs e)
        {
            if (base.ImplementsPackager())
            {
                ClientTools.Library.Templates.TemplateCollection templateCollection = ((Library.Interfaces.IPackager)base.ActProvider).GetTemplates();
                Dialogs.AddDialog dlg = new ClientTools.Client.Controls.Packager.Dialogs.AddDialog();
                dlg.DataSource = templateCollection;
                if (dlg.ShowDialog(this) == DialogResult.OK)
                {
                    ClientTools.Library.Templates.Template selectedItem = (ClientTools.Library.Templates.Template)dlg.SelectedItem;
                    if (selectedItem == null)
                    {
                        MessageBox.Show("No template selected...", "Error", MessageBoxButtons.OK);
                        return;
                    }
                    PackageClasses.Template t = new ClientTools.Client.Controls.Packager.PackageClasses.Template();
                    t.Alias = selectedItem.Alias;
                    t.Design = selectedItem.Design;
                    t.Master = selectedItem.MasterTemplate;
                    t.Name = selectedItem.Name;

                    this._umbPackage.Templates.Add(t);
                }
            }
        }

        private void tsbAddDocumentTypeFromUmbraco_Click(object sender, EventArgs e)
        {
            if (base.ImplementsPackager())
            {
                ClientTools.Library.DocumentTypes.DocumentTypeCollection documentTypeCollection = ((Library.Interfaces.IPackager)base.ActProvider).GetDocumentTypes();
                Dialogs.AddDialog dlg = new ClientTools.Client.Controls.Packager.Dialogs.AddDialog();
                dlg.DataSource = documentTypeCollection;
                if (dlg.ShowDialog(this) == DialogResult.OK)
                {
                    ClientTools.Library.DocumentTypes.DocumentType selectedItem = (ClientTools.Library.DocumentTypes.DocumentType)dlg.SelectedItem;
                    if (selectedItem == null)
                    {
                        MessageBox.Show("No document type selected...", "Error", MessageBoxButtons.OK);
                        return;
                    }
                    PackageClasses.DocumentType docType = new ClientTools.Client.Controls.Packager.PackageClasses.DocumentType();
                    docType.Alias = selectedItem.Alias;
                    docType.Info.Alias = selectedItem.Alias;
                    docType.Info.Name = selectedItem.Name;
                    foreach (string selectedTemplate in selectedItem.Templates)
                    {
                        PackageClasses.AllowedTemplate template = new ClientTools.Client.Controls.Packager.PackageClasses.AllowedTemplate();
                        template.Template = selectedTemplate;
                        docType.Info.AllowedTemplates.Add(template);
                    }
                    docType.Info.DefaultTemplate = selectedItem.DefaultTemplate;
                    docType.Info.Icon = selectedItem.Icon;
                    docType.Info.Name = selectedItem.Name;
                    docType.Info.Thumbnail = selectedItem.Thumbnail;
                    foreach (string selectedChild in selectedItem.AllowedChilds)
	                {
		                PackageClasses.Structure structure = new ClientTools.Client.Controls.Packager.PackageClasses.Structure();
                        structure.DocumentType = selectedChild;
                        docType.Structure.Add(structure);
	                }
                    foreach (ClientTools.Library.DocumentTypes.Tab selectedTab in selectedItem.Tabs)
                    {
                        PackageClasses.Tab tab = new ClientTools.Client.Controls.Packager.PackageClasses.Tab();
                        tab.Caption = selectedTab.Caption;
                        tab.Id = selectedTab.Id;
                        docType.Tabs.Add(tab);
                    }
                    foreach (ClientTools.Library.DocumentTypes.GenericProperty selectedGenProp in selectedItem.GenericProperties)
                    {
                        PackageClasses.GenericProperty genProp = new ClientTools.Client.Controls.Packager.PackageClasses.GenericProperty();
                        genProp.Alias = selectedGenProp.Alias;
                        genProp.Description = selectedGenProp.Description;
                        genProp.Mandatory = selectedGenProp.Mandatory;
                        genProp.Name = selectedGenProp.Name;
                        genProp.Tab = selectedGenProp.Tab;
                        genProp.Type = selectedGenProp.Type;
                        genProp.Validation = selectedGenProp.Validation;
                        docType.GenericProperties.Add(genProp);
                    }
                    this._umbPackage.DocumentTypes.Add(docType);
                }
            }

        }

        private void SavePackageFile() 
        {
            XmlSerializer ser = new XmlSerializer(typeof(PackageClasses.UmbPackage));
            using (FileStream fs = new FileStream(this._packageFilePath, FileMode.Create))
            {
                ser.Serialize(fs, this._umbPackage);
                fs.Close();
            }
        }

        private void SavePackage()
        {
            this.Cursor = Cursors.WaitCursor;
            using (ZipOutputStream zip = new ZipOutputStream(System.IO.File.Create(this._packagePath)))
            {
                ZipEntry entry;
                zip.SetLevel(9); // 0-9, 9 being the highest compression
                byte[] buffer = new byte[4096];
                foreach (PackageClasses.File file in this._umbPackage.Files)
                {
                    if (!System.IO.File.Exists(file.FilePath)) 
                    {
                        this.Cursor = Cursors.Default; 
                        MessageBox.Show("File '" + file.OrgName + "' doesn't exist!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    entry = new ZipEntry(Path.GetFileName(file.FilePath));
                    entry.DateTime = DateTime.Now;
                    zip.PutNextEntry(entry);
                    using (FileStream fs = System.IO.File.OpenRead(file.FilePath))
                    {
                        int sourceBytes;
                        do
                        {
                            sourceBytes = fs.Read(buffer, 0, buffer.Length);
                            zip.Write(buffer, 0, sourceBytes);
                        }
                        while (sourceBytes > 0);
                    }
                }
                entry = new ZipEntry("package.xml");
                entry.DateTime = DateTime.Now;
                zip.PutNextEntry(entry);

                XmlSerializer ser = new XmlSerializer(typeof(PackageClasses.UmbPackage));
                using (MemoryStream mm = new MemoryStream())
                {
                    ser.Serialize(mm, this._umbPackage);
                    mm.Position = 0;
                    buffer = new byte[mm.Length];
                    mm.Read(buffer, 0, (int)mm.Length);
                    zip.Write(buffer, 0, (int)mm.Length);
                }
                zip.Finish();
                zip.Close();
            }
            MessageBox.Show("Package saved", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
            this.Cursor = Cursors.Default;
        }

        private void tsbSave_Click(object sender, EventArgs e)
        {
            if (this._umbPackage == null)
            {
                MessageBox.Show("No package file...", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            switch (this._packagerUsage)
            {
                case PackagerUsageEnum.NotDefined:
                    MessageBox.Show("???", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case PackagerUsageEnum.NewPackage:
                    SaveFileDialog dlg = new SaveFileDialog();
                    dlg.CheckFileExists = false;
                    dlg.CheckPathExists = true;
                    dlg.Filter = "Umbraco package|*.umb|All files|*.*";
                    if (dlg.ShowDialog(this) == DialogResult.OK)
                    {
                        this._packagePath = dlg.FileName;
                        this.SavePackage();
                    }
                    break;
                case PackagerUsageEnum.NewPackageFile:
                    dlg = new SaveFileDialog();
                    dlg.CheckFileExists = false;
                    dlg.CheckPathExists = true;
                    dlg.FileName = "package.xml";
                    dlg.Filter = "Umbraco package file|package.xml|All files|*.*";
                    if (dlg.ShowDialog(this) == DialogResult.OK)
                    {
                        this._packageFilePath = dlg.FileName;
                        this.SavePackageFile();
                        this._packagerUsage = PackagerUsageEnum.OpenPackageFile;
                    }
                    break;
                case PackagerUsageEnum.OpenPackage:
                    this.SavePackage();
                    break;
                case PackagerUsageEnum.OpenPackageFile:
                    this.SavePackageFile();
                    break;
                default:
                    break;
            }
        }

        private void tsbAddExistingFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.CheckFileExists = true;
            dlg.CheckPathExists = true;
            dlg.Filter = "DLLs|*.dll|Webforms (*.aspx)|*.aspx|Web user controls (*.ascx)|*.ascx|All files (*.*)|*.*";
            dlg.Multiselect = true;
            dlg.Title = "Select file(s) to add";
            if (dlg.ShowDialog(this) == DialogResult.OK)
            {
                foreach (string fileName in dlg.FileNames)
                {
                    PackageClasses.File file = new ClientTools.Client.Controls.Packager.PackageClasses.File();
                    file.FilePath = fileName;
                    file.Guid = System.IO.Path.GetFileName(fileName);
                    file.OrgName = file.Guid;
                    file.OrgPath = "/PathToFolderOnWebserver/";
                    this._umbPackage.Files.Add(file);
                }
            }
        }

        private void tsbNewTemplate_Click(object sender, EventArgs e)
        {
            PackageClasses.Template t = new ClientTools.Client.Controls.Packager.PackageClasses.Template();
            t.Alias = "Alias";
            t.Design = "Enter template content here...";
            t.Master = "";
            t.Name = "Template name";
            this._umbPackage.Templates.Add(t);
        }

        private void tsbDeleteTemplate_Click(object sender, EventArgs e)
        {
            if (this.dgvTemplates.SelectedRows.Count == 1)
            {
                this._umbPackage.Templates.Remove((PackageClasses.Template)this.dgvTemplates.SelectedRows[0].DataBoundItem);
            }
        }

        private void tsbNewStylesheet_Click(object sender, EventArgs e)
        {
            PackageClasses.Stylesheet newStylesheet = new ClientTools.Client.Controls.Packager.PackageClasses.Stylesheet();
            newStylesheet.Content = "Enter here the stylesheet content...";
            newStylesheet.FileName = "";
            newStylesheet.Name = "NewStylesheet";
            this._umbPackage.Stylesheets.Add(newStylesheet);
        }

        private void tsbDeleteStylesheet_Click(object sender, EventArgs e)
        {
            if (this.dgvStylesheets.SelectedRows.Count == 1)
            {
                this._umbPackage.Stylesheets.Remove((PackageClasses.Stylesheet)this.dgvStylesheets.SelectedRows[0].DataBoundItem);
            }
        }

        private void tsbNewDocument_Click(object sender, EventArgs e)
        {
            PackageClasses.DocumentSet ds = new ClientTools.Client.Controls.Packager.PackageClasses.DocumentSet();
            ds.ImportMode = "root";
            
        }

        private void tsbDeleteDocument_Click(object sender, EventArgs e)
        {
            if (this.dgvDocuments.SelectedRows.Count == 1)
            {
                this._umbPackage.Documents.Remove((PackageClasses.DocumentSet)this.dgvDocuments.SelectedRows[0].DataBoundItem);
            }
        }
    }
}
